﻿using System;
using System.Linq.Expressions;

using mvcForum.Core.Interfaces.Data;

namespace mvcForum.Core.Specifications {

	public static class ForumUserSpecifications {

		public class SpecificProviderUserKey : ISpecification<ForumUser> {
			private readonly String providerUserKey;

			public SpecificProviderUserKey(String providerUserKey) {
				this.providerUserKey = providerUserKey;
			}

			public Expression<Func<ForumUser, Boolean>> IsSatisfied {
				get {
					return x => x.ProviderId == providerUserKey;
				}
			}
		}

		public class SpecificUsername : ISpecification<ForumUser> {
			private readonly String username;

			public SpecificUsername(String username) {
				this.username = username;
			}

			public Expression<Func<ForumUser, Boolean>> IsSatisfied {
				get {
					return x => x.Name == username;
				}
			}
		}

		public class SpecificEmailAddress : ISpecification<ForumUser> {
			private readonly String email;

			public SpecificEmailAddress(String email) {
				this.email = email;
			}

			public Expression<Func<ForumUser, Boolean>> IsSatisfied {
				get {
					return x => x.EmailAddress == email;
				}
			}
		}

		/// <summary>
		/// This specification can be used to find out whether or not an existing user exist with the given username og email address.
		/// </summary>
		public class ExistingForumUser : ISpecification<ForumUser> {
			private readonly String username;
			private readonly String email;

			public ExistingForumUser(String username, String email) {
				this.email = email;
				this.username = username;
			}

			public Expression<Func<ForumUser, Boolean>> IsSatisfied {
				get {
					return x => x.EmailAddress == email || x.Name == username;
				}
			}
		}

		public class NotDeleted : ISpecification<ForumUser> {

			public NotDeleted() { }

			public Expression<Func<ForumUser, Boolean>> IsSatisfied {
				get {
					return u => u.Deleted == false;
				}
			}
		}

		public class Search : ISpecification<ForumUser> {
			private readonly String query;

			public Search(String query) {
				this.query = query;
			}

			public Expression<Func<ForumUser, Boolean>> IsSatisfied {
				get {
					return u => u.EmailAddress.Contains(query) ||
								u.FullName.Contains(query) ||
								u.Name.Contains(query);
				}
			}
		}
	}
}